#ifndef __WIZ_DATATYPE_SET_HPP__SHANHAOBO_19800429__
#define __WIZ_DATATYPE_SET_HPP__SHANHAOBO_19800429__

#include <set>

#include "../../Base/WizBase.hpp"
#include "./WizDataTypeForEach.hpp"

#define WIZ_DECLARE_SET(t)                                  \
    namespace Set                                           \
    {                                                       \
    WIZ_DECLARE(::Wiz::Set::Type<t>);                       \
    typedef Type::tIterator         tIterator;              \
    typedef Type::tIteratorConst    tIteratorConst;         \
    typedef Type::tForEach          tForEach;               \
    typedef Type::tForEachConst     tForEachConst;          \
    typedef Type::tForEachIter      tForEachIter;           \
    }

namespace Wiz
{
    namespace Set
    {
        template<class ElementT, class CompT = ::std::less<ElementT>>
        struct Type : private ::std::set<ElementT, CompT>
        {
            //////////////////////////////////////////////////////////////////////////
            typedef ElementT                                        tElement;
            typedef const ElementT                                  tElementConst;
            typedef ::std::set<tElement, CompT>                     tSuper;
            typedef ::Wiz::Set::Type<tElement, CompT>               tThis;
            typedef typename tSuper::iterator                       tIterator;
            typedef typename tSuper::const_iterator                 tIteratorConst;
            typedef typename tSuper::reverse_iterator               tReverseIterator;
            typedef typename tSuper::const_reverse_iterator         tConstReverseIterator;
            typedef typename tSuper::iterator::value_type           tValue;
            typedef typename tSuper::const_iterator::value_type     tValueConst;
            typedef typename tSuper::reference                      tReference;
            typedef typename tSuper::const_reference                tReferenceConst;
			//////////////////////////////////////////////////////////////////////////
		public:
			Type() : tSuper(){}
			Type(const tSuper& InSuper) : tSuper(InSuper){}
		public:
            tIterator Begin()
            {
                return tSuper::begin();
            }

            tIteratorConst Begin() const
            {
                return tSuper::begin();
            }

            tIterator End()
            {
                return tSuper::end();
            }

            tIteratorConst End() const
            {
                return tSuper::end();
            }

            ///-----------------------///

            tReverseIterator RBegin()
            {
                return tSuper::rbegin();
            }

            tConstReverseIterator RBegin() const
            {
                return tSuper::rbegin();
            }

            tReverseIterator REnd()
            {
                return tSuper::rend();
            }

            tConstReverseIterator REnd() const
            {
                return tSuper::rend();
            }

            ///-----------------------///

            ::Wiz::Size::Type Size() const
            {
                return ::Wiz::Cast::Static<::Wiz::Size::Type>(tSuper::size());
            }

            ::Wiz::Void::Type Clear()
            {
                tSuper::clear();
            }

            tIterator Erase(tIterator itr)
            {
                return tSuper::erase(itr);
            }

            ///-----------------------///

            tIterator Find(const tElement& v)
            {
                return tSuper::find(v);
            }

            tIteratorConst Find(const tElement& v) const
            {
                return tSuper::find(v);
            }

            ::Wiz::Bool::Type Find(const tElement& v, tIterator& OItr)
            {
                OItr = Find(v);
                return OItr != End();
            }

            ::Wiz::Bool::Type Find(const tElement& v, tIteratorConst& OItr) const
            {
                OItr = Find(v);
                return OItr != End();
            }

            ///-----------------------///

            ::Wiz::Bool::Type HasData(const tElement& v) const
            {
                return tSuper::find(v) != tSuper::end();
            }

            ///-----------------------///

            ::Wiz::Bool::Type Insert(const tElement& i)
            {
                ::std::pair<tIterator, ::Wiz::Bool::Type> Result;

                Result = tSuper::insert(i);

                return Result.second;
            }

            ::Wiz::Bool::Type Insert(const tElement& i, tIterator& Itr)
            {
                ::std::pair<tIterator, ::Wiz::Bool::Type> Result;

                Result = tSuper::insert(i);
                Itr = Result.first;
                return Result.second;
            }


            ::Wiz::Bool::Type InsertUnique(tElement Val)
            {
                if (this->Find(Val) == this->End())
                {
                    this->Insert(Val);
                    return ::Wiz::Bool::True;
                }
                return ::Wiz::Bool::False;
            }

            ::Wiz::Bool::Type InsertUnique(tElement Val, tIterator& Itr)
            {
                if (this->Find(Val) == this->End())
                {
                    Itr = this->Insert(Val);
                    return ::Wiz::Bool::True;
                }
                return ::Wiz::Bool::False;
            }

            ::Wiz::Bool::Type Remove(const tElement& ELT)
            {
                tIterator Found = Find(ELT);
                if (Found == End())
                {
                    return ::Wiz::Bool::False;
                }

                this->Erase(Found);
                return ::Wiz::Bool::True;
            }

            ::Wiz::Bool::Type Remove(const tElement& ELT, tIterator& Itr)
            {
                tIterator Found = Find(ELT);
                if (Found == End())
                {
                    return ::Wiz::Bool::False;
                }

                Itr = this->Erase(Found);
                return ::Wiz::Bool::True;
            }

            ///-----------------------///

            template<class FuncT>
            tIterator FindIf(FuncT Func)
            {
                return ::std::find_if(tSuper::begin(), tSuper::end(), Func);
            }

            template<class FuncT>
            ::Wiz::Void::Type RemoveIf(FuncT Func)
            {
                tSuper::iterator newend = ::std::remove_if(tSuper::begin(), tSuper::end(), Func);
                tSuper::erase(newend, tSuper::end());
            }

            ///-----------------------///

            //////////////////////////////////////////////////////////////////////////
            typedef ::Wiz::ForEach::Type<::Wiz::Set::Type<tElement, CompT>>       tForEach;
            typedef ::Wiz::ConstForEach::Type<::Wiz::Set::Type<tElement, CompT>>  tForEachConst;

            typedef ::Wiz::ForEachIter::Type<::Wiz::Set::Type<tElement, CompT>>   tForEachIter;
            //////////////////////////////////////////////////////////////////////////

            ::Wiz::Void::Type Merge(tThis Temp)
            {
                tIterator Curr;
                tForEach FE(Curr, Temp);

                while (FE.HasMoreElement())
                {
                    Insert(*Curr);
                }
            }
        };
    } /// end of namespace Set
} /// end of namespace Wiz

#endif /*__WIZ_DATATYPE_SET_HPP__SHANHAOBO_19800429__*/
